// 柯理化函数含义： 是给函数分步传递参数，每次传递部分参数，并返回一个更具体的函数接收剩下的参数，这中间可嵌套多层这样的接收部分参数的函数，直至返回最后结果。
// add的参数不固定，看有几个数字累计相加
//TODO 柯里化和偏函数应用的主要意义就是固定一些我们已知的参数，然后返回一个函数继续等待接收那些未知的参数。
function add(a, b, c, d) {
	return a + b + c + d
}

function currying(fn, ...args) {
	if (fn.length === args.length) return fn(...args)

	// 继续分步传递参数 newArgs 新一次传递的参数
	return function (...newArgs) {
		// 将先传递的参数和后传递的参数 结合在一起
		return currying(fn, ...[...args, ...newArgs])
	}
}

let fn1 = currying(add, 1, 2) // function
let fn2 = fn1(3) // function
let fn3 = fn2(4) // 10

// TODO 偏函数 有点类似柯里化
// 这是偏函数，固定了你函数的某一个或几个参数，返回一个新的函数，接收剩下的参数, 参数个数可能是1个，也可能是2个，甚至更多。
function add(a, b, c) {
	return a + b + c
}
function partial(fn) {
	const arg = Array.prototype.slice.call(arguments, 1)
	return function () {
		return fn(...arg, ...arguments)
	}
}
var fn = partial(add, 1)
// 效果等同上面
// var fn = add.bind(null, 1)
var res = fn(2, 3) // 6
console.log(res)
